




package com.yinhai.ta404.component.org.orguser.user.service.write.impl;

import com.yinhai.ta404.component.examine.annotation.Examine;
import com.yinhai.ta404.component.examine.common.TargetType;
import com.yinhai.ta404.component.org.core.service.impl.OrgBaseService;
import com.yinhai.ta404.component.org.core.vo.TaOrgVo;
import com.yinhai.ta404.component.org.core.vo.TaUserVo;
import com.yinhai.ta404.component.org.orguser.org.mapper.read.OrgManagementReadMapper;
import com.yinhai.ta404.component.org.orguser.user.entity.TaAvatarPo;
import com.yinhai.ta404.component.org.orguser.user.entity.TaObjectTagPo;
import com.yinhai.ta404.component.org.orguser.user.entity.TaUserPo;
import com.yinhai.ta404.component.org.orguser.user.mapper.read.UserManagementReadMapper;
import com.yinhai.ta404.component.org.orguser.user.mapper.write.UserManagementWriteMapper;
import com.yinhai.ta404.component.org.orguser.user.service.write.UserManagementWriteService;
import com.yinhai.ta404.component.org.orguser.userorg.entity.TaUserOrgPo;
import com.yinhai.ta404.component.org.orguser.userorg.mapper.write.UserOrgWriteMapper;
import com.yinhai.ta404.component.org.orguser.userorg.service.read.UserOrgReadService;
import com.yinhai.ta404.component.org.orguser.userorg.service.write.UserOrgWriteService;
import com.yinhai.ta404.core.exception.AppException;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import com.yinhai.ta404.core.utils.FileTypeUtil;
import com.yinhai.ta404.core.utils.JsonFactory;
import com.yinhai.ta404.core.utils.ObjectConversionUtil;
import com.yinhai.ta404.core.utils.StringUtils;
import com.yinhai.ta404.core.utils.ValidateUtil;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
@TaTransactional
public class UserManagementWriteServiceImpl extends OrgBaseService implements UserManagementWriteService {
    @Resource
    private UserManagementWriteMapper userManagementWriteMapper;
    @Resource
    private UserManagementReadMapper userManagementReadMapper;
    @Resource
    private UserOrgWriteService userOrgWriteService;
    @Resource
    private UserOrgReadService userOrgReadService;
    @Resource
    private OrgManagementReadMapper orgManagementReadMapper;
    @Resource(
            name = "taPasswordEncoder"
    )
    private PasswordEncoder encoder;

    public UserManagementWriteServiceImpl() {
    }

    @Override
    @Examine(
            operator_name = "批量删除人员",
            resultBeanName = "userResult",
            resultMethodName = "batchUserResult",
            targetType = TargetType.USER
    )
    public void deleteBatchUserByUserIds(List<String> userIds) {
        if (this.permissionValidateService.checkUserPermissionByUserIds(userIds, "1")) {
            this.orgOpLogEventPublish.pubUserOpLogEvent("14", JsonFactory.bean2json(userIds), (String)null, "0");
            throw new AppException("无权限删除人员信息，操作失败！");
        } else {
            this.deleteUserByUserIdList(userIds);
        }
    }

    @Examine(
            operator_name = "更新人员",
            resultBeanName = "userResult",
            resultMethodName = "updateUserResult",
            targetType = TargetType.USER
    )
    public int updateUserByUserId(TaUserVo updateVo) {
        TaUserVo oldUserVo = this.userManagementReadMapper.queryUserVoByUserId(updateVo.getUserId(), "0");
        if (this.permissionValidateService.checkUserPermission(updateVo.getUserId(), "1")) {
            this.orgOpLogEventPublish.pubUserOpLogEvent("07", updateVo.getUserId(), JsonFactory.bean2json(oldUserVo) + "->" + JsonFactory.bean2json(updateVo), "0");
            throw new AppException("无权限编辑人员信息，操作失败！");
        } else {
            this.checkJobNumber(updateVo.getUserId(), updateVo.getJobNumber());
            int result = this.userManagementWriteMapper.updateUserByUserId((TaUserPo)ObjectConversionUtil.convert(new TaUserPo(), updateVo));
            String avatar = updateVo.getPortrait();
            if (StringUtils.isNotEmpty(avatar)) {
                byte[] decode = Base64.getDecoder().decode(avatar.split(",")[1]);
                if (!FileTypeUtil.isImage(new ByteArrayInputStream(decode))) {
                    throw new AppException("上传文件非图片类型，请确认");
                }

                TaAvatarPo taAvatarPo = new TaAvatarPo();
                taAvatarPo.setAvatar(avatar.getBytes(StandardCharsets.UTF_8));
                taAvatarPo.setUserId(updateVo.getUserId());
                taAvatarPo.setUpdateTime(this.getSysTimestamp());
                TaAvatarPo hasAvatar = this.userManagementReadMapper.selectAvatarByUserId(updateVo.getUserId());
                if (hasAvatar == null) {
                    this.userManagementWriteMapper.addAvatar(taAvatarPo);
                } else if (hasAvatar.getAvatar() == null || !avatar.equals(new String(hasAvatar.getAvatar(), StandardCharsets.UTF_8))) {
                    this.userManagementWriteMapper.updateAvatar(taAvatarPo);
                }
            } else {
                this.userManagementWriteMapper.deleteAvatarByUserId(updateVo.getUserId());
            }

            this.userManagementWriteMapper.deleteObjectTagByUserId(updateVo.getUserId());
            String tags = updateVo.getTags();
            if (ValidateUtil.isNotEmpty(tags)) {
                List<String> tagList = StringUtils.string2List(tags);
                tagList.forEach((tag) -> {
                    TaObjectTagPo addTagPo = new TaObjectTagPo();
                    addTagPo.setObjectId(updateVo.getUserId());
                    addTagPo.setObjectType("001");
                    addTagPo.setTagId(tag);
                    this.userManagementWriteMapper.insertUserTag(addTagPo);
                });
            }

            this.orgOpLogEventPublish.pubUserOpLogEvent("07", updateVo.getUserId(), JsonFactory.bean2json(oldUserVo) + "->" + JsonFactory.bean2json(updateVo), "1");
            this.eventPublish.publish(updateVo.getUserId(), "USER_UPDATE");
            return result;
        }
    }

    private void checkJobNumber(String userId, String jobNumber) {
        if (!ValidateUtil.isEmpty(jobNumber)) {
            List<TaUserVo> userVos = this.userManagementReadMapper.queryUserInfoByJobNumber(jobNumber, "0");
            if (!userVos.isEmpty()) {
                if (userVos.size() == 1) {
                    if (!((TaUserVo)userVos.get(0)).getUserId().equals(userId)) {
                        throw new AppException("工号[" + jobNumber + "]已被使用！");
                    }
                } else {
                    throw new AppException("工号[" + jobNumber + "]已被使用！");
                }
            }
        }
    }

    @Override
    @Examine(
            operator_name = "新增人员",
            resultBeanName = "userResult",
            resultMethodName = "addUserResult",
            targetType = TargetType.USER
    )
    public int addUser(TaUserVo addVo) {
        if (this.permissionValidateService.checkOrgPermission(addVo.getOrgId(), "1")) {
            this.orgOpLogEventPublish.pubUserOpLogEvent("06", addVo.getUserId(), JsonFactory.bean2json(addVo), "0");
            throw new AppException("无权限在该组织下新增人员，操作失败！");
        } else {
            TaOrgVo orgVo = this.orgManagementReadMapper.queryOrgByOrgId(addVo.getOrgId(), "0");
            if ("0".equals(orgVo.getEffective())) {
                throw new AppException("组织[" + orgVo.getOrgName() + "]已禁用，无法新增人员，请刷新页面。");
            } else {
                int count = this.userManagementReadMapper.queryUserExistLoginId(addVo.getLoginId().trim(), "0");
                if (count > 0) {
                    throw new AppException("该账号已被使用，请更换后再试。");
                } else {
                    this.checkJobNumber(addVo.getUserId(), addVo.getJobNumber());
                    Timestamp curDate = this.getSysTimestamp();
                    addVo.setCreateTime(curDate);
                    addVo.setPasswordDefaultNum(this.orgConfig.getPasswordDefaultNum().toString());
                    addVo.setIsLock("0");
                    addVo.setDestory("0");
                    if (ValidateUtil.isEmpty(addVo.getEffective())) {
                        addVo.setEffective("1");
                    }

                    TaUserPo addPo = (TaUserPo)ObjectConversionUtil.convert(new TaUserPo(), addVo);
                    addPo.setPassword(this.encoder.encode(addPo.getPassword()));
                    int addUser = this.userManagementWriteMapper.addUser(addPo);
                    String userId = addPo.getUserId();
                    if (addUser == 0) {
                        return 0;
                    } else {
                        TaUserOrgPo userOrgPo = new TaUserOrgPo();
                        if ("1".equals(this.orgConfig.getMultipleOrg())) {
                            userOrgPo.setIsDirect("0");
                        } else {
                            userOrgPo.setIsDirect("1");
                        }

                        userOrgPo.setUserId(addVo.getUserId());
                        userOrgPo.setOrgId(addVo.getOrgId());
                        this.userOrgWriteService.addUserOrg(userOrgPo);
                        TaUserOrgPo virtualUserOrgPo = new TaUserOrgPo();
                        virtualUserOrgPo.setUserId(addVo.getUserId());
                        virtualUserOrgPo.setOrgId(this.rootConfig.getVirtualOrgId());
                        virtualUserOrgPo.setIsDirect("0");
                        this.userOrgWriteService.addUserOrg(virtualUserOrgPo);
                        if (StringUtils.isNotEmpty(addVo.getPortrait())) {
                            TaAvatarPo taAvatarPo = new TaAvatarPo();
                            taAvatarPo.setUserId(userId);
                            taAvatarPo.setAvatar(addVo.getPortrait().getBytes(StandardCharsets.UTF_8));
                            taAvatarPo.setUpdateTime(curDate);
                            byte[] decode = Base64.getDecoder().decode(addVo.getPortrait().split(",")[1]);
                            if (!FileTypeUtil.isImage(new ByteArrayInputStream(decode))) {
                                throw new AppException("上传文件非图片类型，请确认");
                            }

                            this.userManagementWriteMapper.addAvatar(taAvatarPo);
                        }

                        String tags = addVo.getTags();
                        if (ValidateUtil.isNotEmpty(tags)) {
                            List<String> tagList = StringUtils.string2List(tags);
                            tagList.forEach((tag) -> {
                                TaObjectTagPo addTagPo = new TaObjectTagPo();
                                addTagPo.setObjectId(userId);
                                addTagPo.setObjectType("001");
                                addTagPo.setTagId(tag);
                                this.userManagementWriteMapper.insertUserTag(addTagPo);
                            });
                        }

                        this.orgOpLogEventPublish.pubUserOpLogEvent("06", addVo.getUserId(), (String)null, "1");
                        this.eventPublish.publish(addVo.getUserId(), "USER_ADD");
                        return addUser;
                    }
                }
            }
        }
    }

    @Override
    @Examine(
            operator_name = "批量禁用人员",
            resultBeanName = "userResult",
            resultMethodName = "batchUserResult",
            targetType = TargetType.USER
    )
    public void updateBatchUserDisable(List<String> userIds) {
        if (!ValidateUtil.isEmpty(userIds)) {
            if (this.permissionValidateService.checkUserPermissionByUserIds(userIds, "1")) {
                this.orgOpLogEventPublish.pubUserOpLogEvent("08", JsonFactory.bean2json(userIds), (String)null, "0");
                throw new AppException("无权限禁用人员，操作失败！");
            } else {
                List<TaUserVo> vos = this.userManagementReadMapper.queryUserInfo(userIds, "0");
                boolean allInStatus = true;
                Iterator var4 = vos.iterator();

                while(var4.hasNext()) {
                    TaUserVo vo = (TaUserVo)var4.next();
                    if ("1".equals(vo.getEffective())) {
                        allInStatus = false;
                        break;
                    }
                }

                if (allInStatus) {
                    throw new AppException("所有人员均为禁用状态，无法禁用！");
                } else {
                    this.batchService.batchOperation(UserManagementWriteMapper.class, "updateUserEffectiveByUserId", new Object[]{userIds, "0"}, (SqlSessionTemplate)null);
                    this.orgOpLogEventPublish.pubUserOpLogEvent("08", JsonFactory.bean2json(userIds), (String)null, "1");
                    this.eventPublish.publish(userIds, "USER_DISABLE_BATCH");
                }
            }
        }
    }

    @Override
    @Examine(
            operator_name = "批量启用人员",
            resultBeanName = "userResult",
            resultMethodName = "batchUserResult",
            targetType = TargetType.USER
    )
    public void updateBatchUserAble(List<String> userIds) {
        if (this.permissionValidateService.checkUserPermissionByUserIds(userIds, "1")) {
            this.orgOpLogEventPublish.pubUserOpLogEvent("09", JsonFactory.bean2json(userIds), (String)null, "0");
            throw new AppException("无权限启用人员，操作失败！");
        } else {
            List<TaUserVo> vos = this.userManagementReadMapper.queryUserInfo(userIds, "0");
            boolean allInStatus = true;
            Iterator var4 = vos.iterator();

            while(var4.hasNext()) {
                TaUserVo vo = (TaUserVo)var4.next();
                if ("0".equals(vo.getEffective())) {
                    allInStatus = false;
                    break;
                }
            }

            if (allInStatus) {
                throw new AppException("所有人员均为启用状态，无法禁用！");
            } else {
                this.batchService.batchOperation(UserManagementWriteMapper.class, "updateUserEffectiveByUserId", new Object[]{userIds, "1"}, (SqlSessionTemplate)null);
                this.orgOpLogEventPublish.pubUserOpLogEvent("09", JsonFactory.bean2json(userIds), (String)null, "1");
                this.eventPublish.publish(userIds, "USER_ENABLE_BATCH");
            }
        }
    }

    @Override
    @Examine(
            operator_name = "批量解锁人员",
            resultBeanName = "userResult",
            resultMethodName = "batchUserResult",
            targetType = TargetType.USER
    )
    public void updateBatchUserLock(List<String> userIds) {
        int defaultPassNum = this.orgConfig.getPasswordDefaultNum();
        if (this.permissionValidateService.checkUserPermissionByUserIds(userIds, "1")) {
            this.orgOpLogEventPublish.pubUserOpLogEvent("11", JsonFactory.bean2json(userIds), this.orgConfig.getPasswordDefaultNum().toString(), "0");
            throw new AppException("无权限解锁人员！");
        } else {
            this.batchService.batchOperation(UserManagementWriteMapper.class, "updateUserLockByUserId", new Object[]{userIds, "0", defaultPassNum}, (SqlSessionTemplate)null);
            this.orgOpLogEventPublish.pubUserOpLogEvent("11", JsonFactory.bean2json(userIds), this.orgConfig.getPasswordDefaultNum().toString(), "1");
            this.eventPublish.publish(userIds, "USER_UNLOCK_BATCH");
        }
    }

    @Override
    public int updateUserPwdByUserId(String userId, String password) {
        int result = this.userManagementWriteMapper.updateUserPwdByUserId(userId, this.encoder.encode(password), this.getSysDate());
        this.eventPublish.publish(userId, "USER_PW_UPDATE");
        return result;
    }

    @Override
    @Examine(
            operator_name = "修改人员密码",
            resultBeanName = "userResult",
            resultMethodName = "userPwdResult",
            targetType = TargetType.USER
    )
    public int updateUserPwdByUserIdForAdmin(String userId, String password) {
        TaUserVo userVo = this.userManagementReadMapper.queryUserVoByUserId(userId, "0");
        if (this.permissionValidateService.checkUserPermission(userId, "1")) {
            this.orgOpLogEventPublish.pubUserOpLogEvent("13", userId, userVo.getPassword() + "->" + password, "0");
            throw new AppException("无权限重置人员密码，操作失败！");
        } else {
            int result = this.userManagementWriteMapper.updateUserPwdByUserId(userId, this.encoder.encode(password), (Date)null);
            this.orgOpLogEventPublish.pubUserOpLogEvent("13", userId, userVo.getPassword() + "->" + password, "1");
            this.eventPublish.publish(userId, "USER_PW_UPDATE_ADMIN");
            return result;
        }
    }

    @Override
    public void updateOrInsertUserOrgByUserId(TaUserVo taUserVo) {
        if (this.permissionValidateService.checkOrgPermission(taUserVo.getOrgId(), "1")) {
            this.orgOpLogEventPublish.pubUserOpLogEvent("12", taUserVo.getUserId(), JsonFactory.bean2json(taUserVo), "0");
            throw new AppException("无权限修改人员所属组织机构，操作失败！");
        } else if ("1".equals(this.orgConfig.getMultipleOrg())) {
            throw new AppException("当前模式非[人员只能在单个组织下]与[人员在多个组织且区分主次之分]，请调整配置！");
        } else {
            TaUserVo userVo = this.userManagementReadMapper.queryUserOrgByUserId(taUserVo.getUserId());
            TaUserOrgPo po = new TaUserOrgPo();
            po.setOrgId(taUserVo.getOrgId());
            po.setUserId(taUserVo.getUserId());
            po.setIsDirect("1");
            if (ValidateUtil.isEmpty(userVo)) {
                this.userOrgWriteService.addUserOrg(po);
                this.orgOpLogEventPublish.pubUserOpLogEvent("12", taUserVo.getUserId(), JsonFactory.bean2json(po), "1");
            } else {
                this.userOrgWriteService.updateUserOrgByUserId(po);
                this.orgOpLogEventPublish.pubUserOpLogEvent("12", taUserVo.getUserId(), JsonFactory.bean2json(userVo) + "->" + JsonFactory.bean2json(po), "1");
                this.eventPublish.publish(taUserVo.getUserId(), "USER_ORG_UPDATE");
            }
        }
    }

    @Override
    public int updateUserPasswordNumByUserId(String userId, int passwordDefaultNum, String isLock) {
        return 1;//this.userManagementWriteMapper.updateUserLockByUserId(userId, isLock, passwordDefaultNum);
    }

    @Override
    @Examine(
            operator_name = "重置人员密码",
            resultBeanName = "userResult",
            resultMethodName = "userPwdResult",
            targetType = TargetType.USER
    )
    public void resetUserPwByAdmin(String userId, String passWd) {
        if (ValidateUtil.isEmpty(userId)) {
            throw new AppException("账户唯一标识为空，无法重置密码！");
        } else {
            if (ValidateUtil.isEmpty(passWd)) {
                passWd = this.orgConfig.getDefaultPw();
            }

            this.userManagementWriteMapper.updateUserPwdByUserId(userId, this.encoder.encode(passWd), this.getSysDate());
        }
    }

    @Override
    public void deleteUserByOrgIdsWithChild(List<String> orgIdList) {
        this.deleteUserByUserIdList(this.userOrgReadService.queryUserIdByOrgIdWIthChild(orgIdList));
    }

    @Override
    public void disableUserByOrgIdsWithChild(List<String> orgIdList) {
        this.updateBatchUserDisable(this.userOrgReadService.queryUserIdByOrgIdWIthChild(orgIdList));
    }

    @Override
    public void enableUserByOrgIdsWithChild(List<String> orgIdList) {
        this.updateBatchUserAble(this.userOrgReadService.queryUserIdByOrgIdWIthChild(orgIdList));
    }

    @Override
    @Examine(
            operator_name = "人员更改组织",
            resultBeanName = "userResult",
            resultMethodName = "updateUserOrgByUserIdResult",
            targetType = TargetType.USER
    )
    public void updateUserOrgByUserId(String userId, List<String> addOrgList, List<String> removeOrgIdList, String directOrgId) {
        Set<String> orgIdSet = new HashSet(addOrgList);
        orgIdSet.addAll(removeOrgIdList);
        orgIdSet.add(directOrgId);
        if (this.permissionValidateService.checkOrgPermissionByOrgIds(new ArrayList(orgIdSet), "1")) {
            this.orgOpLogEventPublish.pubOrgOpLogEvent("12", JsonFactory.bean2json(orgIdSet), (String)null, "0");
            throw new AppException("无对应组织权限，操作失败，请刷新页面！");
        } else if ("1".equals(this.orgConfig.getMultipleOrg()) && ValidateUtil.isNotEmpty(directOrgId)) {
            throw new AppException("当前人员组织模式为[多组织模式]，无法进行调整直属组织！");
        } else {
            if (ValidateUtil.isNotEmpty(removeOrgIdList)) {
                this.userOrgWriteService.deleteUserOrgList((List)removeOrgIdList.stream().map((id) -> {
                    TaUserOrgPo po = new TaUserOrgPo();
                    po.setOrgId(id);
                    po.setUserId(userId);
                    po.setIsDirect("0");
                    return po;
                }).collect(Collectors.toList()));
            }

            TaUserOrgPo userOrgPo = this.userOrgReadService.queryUserOrgDirect(userId);
            if (!ValidateUtil.isEmpty(userOrgPo) && ValidateUtil.isNotEmpty(userOrgPo.getUserId())) {
                this.userOrgWriteService.deleteUserOrgList(Collections.singletonList(userOrgPo));
            }

            List<String> orgIdList = (List)this.userOrgReadService.queryUserOrgByUserId(userId, "0").stream().map(TaUserOrgPo::getOrgId).collect(Collectors.toList());
            if (orgIdList.contains(directOrgId)) {
                throw new AppException("修改组织过程中，组织[" + this.orgCacheService.queryOrgCacheByOrgId(directOrgId).getOrgName() + "]数据错误，一个组织无法同时作为一个账户的'直属组织'和'附属组织'。");
            } else {
                if (ValidateUtil.isNotEmpty(directOrgId)) {
                    TaUserOrgPo directUseOrgPo = new TaUserOrgPo();
                    directUseOrgPo.setOrgId(directOrgId);
                    directUseOrgPo.setUserId(userId);
                    directUseOrgPo.setIsDirect("1");
                    this.userOrgWriteService.addUserOrg(directUseOrgPo);
                }

                if (ValidateUtil.isNotEmpty(addOrgList)) {
                    this.userOrgWriteService.addUserOrgList((List)addOrgList.stream().map((id) -> {
                        TaUserOrgPo po = new TaUserOrgPo();
                        po.setOrgId(id);
                        po.setUserId(userId);
                        po.setIsDirect("0");
                        return po;
                    }).collect(Collectors.toList()));
                }

                Map<String, Object> map = new HashMap(4);
                map.put("addOrgIds", addOrgList);
                map.put("removeOrgIds", removeOrgIdList);
                map.put("directOrgId", directOrgId);
                this.orgOpLogEventPublish.pubUserOpLogEvent("12", userId, JsonFactory.bean2json(map), "1");
                this.eventPublish.publish(userId, "USER_ORG_UPDATE");
            }
        }
    }

    private void deleteUserByUserIdList(List<String> userIdList) {
        if (!ValidateUtil.isEmpty(userIdList)) {
            this.batchService.batchOperation(UserOrgWriteMapper.class, "deleteUserOrgByUserId", new Object[]{userIdList}, (SqlSessionTemplate)null);
            this.batchService.batchOperation(UserManagementWriteMapper.class, "deleteObjectTagByUserId", new Object[]{userIdList}, (SqlSessionTemplate)null);
            this.batchService.batchOperation(UserManagementWriteMapper.class, "deleteUserByUserId", new Object[]{userIdList, "1"}, (SqlSessionTemplate)null);
            this.batchService.batchOperation(UserManagementWriteMapper.class, "deleteAvatarByUserId", new Object[]{userIdList}, (SqlSessionTemplate)null);
            this.orgOpLogEventPublish.pubUserOpLogEvent("14", JsonFactory.bean2json(userIdList), (String)null, "1");
            this.eventPublish.publish(userIdList, "USER_DELETE_BATCH");
        }
    }
}
